package wator.model;

import java.util.Observable;

import wator.model.agents.BigFishAgent;
import wator.model.agents.EnergySharkAgent;
import wator.model.agents.FishAgent;
import wator.model.agents.SharkAgent;
import wator.model.agents.SmallFishAgent;

/**
 * This singleton class defines the current agent configuration. On the basic
 * level, it defines which species exist in the wator world. Furthermore, 
 * parameters global for all individuals of a species (i.e. starvation times) 
 * are organized by this interface.
 * 
 * @see AgentConfiguration
 * @see Agent
 */
final public class AvailableAgents extends Observable {
	
	private static final AvailableAgents singleton = new AvailableAgents();
	
	private AgentConfiguration[] configurations;
	
	/**
	 * This constructor initializes the configuration list by scanning the
	 * <code>wator.model.agents</code> package with java's reflection API.
	 * Also, add the template agents as observers of simulation so that they
	 * are notified if the size vector changes.
	 */
	protected AvailableAgents() {
		// TODO: Load them dynamically
		configurations = new AgentConfiguration[]{
				new AgentConfiguration(new SharkAgent(null)),
				new AgentConfiguration(new EnergySharkAgent(null)),
				new AgentConfiguration(new FishAgent(null)),
				new AgentConfiguration(new SmallFishAgent(null)),
				new AgentConfiguration(new BigFishAgent(null))};
		Simulation s = Simulation.getInstance();
		for (AgentConfiguration ac : configurations) {
			s.addObserver(ac.getTemplate());
		}
	}
	
	/**
	 * Get the singleton instance of <code>AvailableAgents</code>. This is not
	 * a lazy singleton pattern implementation, so the singleton is created at
	 * program start in a static way.
	 *  
	 * @return the singleton instance of <code>AvailableAgents</code>
	 */
	public static AvailableAgents getInstance() {
		return singleton;
	}

	/**
	 * Get an unsorted array of the configurations of available agents, even of
	 * those which are disabled.
	 * 
	 * @return an array of agent configurations
	 */
	public AgentConfiguration[] getConfigurations() {
		return configurations;
	}
}
